package com.sf.fy.uav.applet.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sf.fy.uav.applet.config.DelayQueue;
import com.sf.fy.uav.applet.login.service.LoginService;
import com.sf.fy.uav.applet.operate.controller.AirportInfoController;
import com.sf.fy.uav.applet.order.controller.OrderController;
import com.sf.fy.uav.applet.order.controller.task.TaskController;
import com.sf.fy.uav.applet.order.service.OrderService;
import com.sf.fy.uav.common.request.common.IdRequest;
import com.sf.fy.uav.common.utils.*;
import com.sf.fy.uav.common.awt.JwtUtil;
import com.sf.fy.uav.common.enums.*;
import com.sf.fy.uav.common.request.order.*;
import com.sf.fy.uav.common.request.order.task.ConfirmPayRequest;
import com.sf.fy.uav.common.response.IdResponse;
import com.sf.fy.uav.common.response.order.*;
import com.sf.fy.uav.common.response.order.task.GoodsTypeResponse;
import com.sf.fy.uav.common.response.user.UserResponse;
import com.sf.fy.uav.controller.ErrandOrderController;
import com.sf.fy.uav.controller.UserCouponRest;
import com.sf.fy.uav.entity.*;
import com.sf.fy.uav.good.controller.GoodsTypeRest;
import com.sf.fy.uav.good.entity.CityGoodsType;
import com.sf.fy.uav.good.entity.TaskGoods;
import com.sf.fy.uav.good.mapper.CityGoodsTypeMapper;
import com.sf.fy.uav.good.mapper.TaskGoodsMapper;
import com.sf.fy.uav.mapper.*;
import com.sf.fy.uav.order.controller.*;
import com.sf.fy.uav.order.entity.*;
import com.sf.fy.uav.order.mapper.*;
import com.sf.fy.uav.order.service.IFeedbackService;
import com.sf.fy.uav.order.service.IOrderInfoService;
import com.sf.fy.uav.rest.ActivityRest;
import com.sf.fy.uav.rest.PromotionStatisticsRest;
import com.sf.fy.uav.rest.SysFsRest;
import com.sf.fy.uav.rest.controller.TtTesTerminalRest;
import com.sf.fy.uav.rest.entity.TtTesTerminal;
import com.sf.fy.uav.service.CouponService;
import com.sf.fy.uav.sms.rest.WxAppletRest;
import com.sf.fy.uav.task.controller.TaskStatusLogRest;
import com.sf.fy.uav.task.entity.TaskStatusLog;
import com.sf.fy.uav.task.mapper.TaskStatusLogMapper;
import com.sf.fy.uav.task.rest.IntraCityRest;
import com.sf.fy.uav.user.controller.UserWalletRest;
import com.sf.fy.uav.user.entity.User;
import com.sf.fy.uav.user.mapper.RewardBillMapper;
import com.sf.fy.uav.user.mapper.UserMapper;
import com.sf.fy.uav.user.mapper.UserWalletMapper;
import com.sf.fy.uav.user.rest.UserRest;
import com.sf.fy.uav.withdrawal.mapper.WithdrawalStatisticsMapper;
import com.sf.fy.uav.withdrawal.rest.WithdrawalStatisticsRest;
import com.sfpay.sdk.OpenClient;
import com.sfpay.sdk.entity.request.ApiResponse;
import com.sfpay.sdk.entity.request.trade.*;
import io.seata.core.context.RootContext;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author LTQ
 */
@Service
public class OrderServiceImpl implements OrderService {
    private final static Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

    @Autowired
    private UserWalletMapper userWalletMapper;


    @Value("${pay.sit-url: https://sfpay-sit.sf-pay.com}")
    private String sitUrl;
    @Autowired
    private UserWalletRest userWalletRest;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private IOrderInfoService iOrderInfoService;

    @Autowired
    private OrderController orderController;

    @Autowired
    private ActivityMapper activityMapper;

    @Autowired
    private IntraCityRest intraCityRest;

    @Autowired
    private WithdrawalStatisticsRest withdrawalStatisticsRest;

    @Autowired
    private FeedbackTypeRest feedbackTypeRest;
    @Value("${count.down.pending_items:7}")
    private Integer countDownPendingItems;
    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private TaskController taskController;

    @Autowired
    private TaskStatusLogMapper taskStatusLogMapper;

    @Autowired
    private OrderExtraController orderExtraController;


    @Autowired
    private SysFsRest sysFsRest;

    @Autowired
    private OrderExtraMapper orderExtraMapper;

    @Autowired
    private PaySettingMapper paySettingMapper;

    @Autowired
    private TaskGoodsMapper taskGoodsMapper;

    @Autowired
    private CityAirportRest cityAirportRest;

    @Autowired
    private TaskStatusLogRest taskStatusLogRest;

    @Autowired
    private FeedbackTypeMapper feedbackTypeMapper;

    @Autowired
    private InvitationCodeMapper invitationCodeMapper;

    @Autowired
    private FeedbackStatusLogMapper feedbackStatusLogMapper;

    @Autowired
    private PromotionRecordsMapper promotionRecordsMapper;

    @Autowired
    private PromotionStatisticsMapper promotionStatisticsMapper;

    @Autowired
    private PromotionStatisticsRest promotionStatisticsRest;

    @Autowired
    private PaySettingRest paySettingRest;

    @Autowired
    private PricingRest pricingRest;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${redis.dead:delayQueue}")
    private String DELAY_MESSAGE_QUEUE;
    @Autowired
    private FeedbackRest feedbackRest;

    @Autowired
    private FeedbackMapper feedbackMapper;

    @Autowired
    private IFeedbackService iFeedbackService;

    @Autowired
    private FeedbackStatusLogRest feedbackStatusLogRest;

    @Autowired
    private CityGoodsTypeMapper cityGoodsTypeMapper;

    @Autowired
    private GoodsTypeRest goodsTypeRest;

    @Autowired
    private InvitationRecordMapper invitationRecordMapper;

    @Autowired
    private ActivityRest activityRest;

    @Autowired
    private UserRest userRest;

    @Autowired
    private TtTesTerminalRest ttTesTerminalRest;

    @Autowired
    private ErrandOrderController errandOrderController;

    @Value("${wx.appid:wxe6b1552baf2f3303}")
    private String appid;


    @Value("${wx.sf_appid:wx7871a926d3eb9e45}")
    private String sfAppid;

    @Value("${wx.update-status-template-id:DyZzQXtOw2iXdd63ZETf-40AVO_q8Ip305yplDfs2qc}")
    private String updateStatusTemplateId;

    @Value("${wx.delivery-completed-template-id:2g5ww9uT3wlOhfKdvA34E4OOACSfvjHvXuZCDF60LK8}")
    private String deliveryCompletedTemplateId;


    SimpleDateFormat sdf = new SimpleDateFormat("YYYY年MM月dd日 HH:mm:ss");


    @Value("${pay.notify-url:http://127.0.0.1:8080/trade/callback}")
    private String notifyUrl;


    @Value("${callback.url:https://ie-uocs-out.sit.sf-express.com:4433/uocs-intracity/}")
    private String callbackUrl;

    @Autowired
    private DelayQueue delayQueue;

    @Autowired
    private BillRest billRest;

    @Autowired
    private BillMapper billMapper;

    @Autowired
    private WxAppletRest wxAppletRest;

    @Autowired
    private LoginService loginService;

    @Autowired
    private RewardBillMapper rewardBillMapper;

    @Autowired
    private WithdrawalStatisticsMapper withdrawalStatisticsMapper;

    @Autowired
    private UserCouponMapper userCouponMapper;

    @Autowired
    private CouponService couponService;

    @Autowired
    private PhoneEncoderUtil phoneEncoderUtil;

    @Value("${lock.try_time:3}")
    private long lockTryTime;

    @Autowired
    private UserCouponRest userCouponRest;

    @Autowired
    private CouponMapper couponMapper;

    @Value("${express.fee:20}")
    private BigDecimal expressFee;

    @Autowired
    private ExpenseDetailsMapper expenseDetailsMapper;

    @Autowired
    private AirportInfoController airportInfoController;

    public OrderServiceImpl() {
    }


    @Override
    @Transactional
    public PlaceOrderResponse placeOrder(PrepareOrderRequest prepareOrderRequest) {
        logger.info(prepareOrderRequest.toString());
        String senderTel = prepareOrderRequest.getSenderTel();
        String receiverTel = prepareOrderRequest.getReceiverTel();
        MobileNumberValidatorUtil.checkPhone(senderTel);
        MobileNumberValidatorUtil.checkPhone(receiverTel);
        String fromProvince = prepareOrderRequest.getFromProvince();
        String fromCity = prepareOrderRequest.getFromCity();
        String fromDistrict = prepareOrderRequest.getFromDistrict();
        String toProvince = prepareOrderRequest.getToProvince();
        String toCity = prepareOrderRequest.getToCity();
        String toDistrict = prepareOrderRequest.getToDistrict();
        if (fromProvince.contains("undefined") || fromCity.contains("undefined") || toProvince.contains("undefined") || toCity.contains("undefined")) {
            //传入的城市有问题，通过经纬度反查，比较是否同城
            String senderLat = prepareOrderRequest.getSenderLat();
            String senderLon = prepareOrderRequest.getSenderLon();
            String receiverLat = prepareOrderRequest.getReceiverLat();
            String receiverLon = prepareOrderRequest.getReceiverLon();
            Map<String, Object> stringObjectMap = AddressUtils.getLocation(senderLon, senderLat);
            Map<String, Object> stringObjectMap1 = AddressUtils.getLocation(receiverLon, receiverLat);
            fromProvince = stringObjectMap.get("province").toString();
            fromCity = stringObjectMap.get("city").toString();
            fromDistrict = stringObjectMap.get("district").toString();
            toProvince = stringObjectMap1.get("province").toString();
            toCity = stringObjectMap1.get("city").toString();
            toDistrict = stringObjectMap1.get("district").toString();
        }
        String expenseDetailsId = prepareOrderRequest.getExpenseDetailsId();
        String userCouponId = prepareOrderRequest.getUserCouponId();
        //校验价格是否被篡改
        BigDecimal pricePayable = null;
        if (!ObjectUtils.isEmpty(expenseDetailsId)) {
            ExpenseDetails expenseDetails = expenseDetailsMapper.selectById(expenseDetailsId);
            if (ObjectUtils.isEmpty(expenseDetails)) {
                throw new RuntimeException("费用明细不存在");
            }
            BigDecimal expenseDetailsPricePayable = expenseDetails.getPricePayable();
            BigDecimal reductionPrice = expenseDetails.getReductionPrice();
            pricePayable = iOrderInfoService.newCheckPrice(expenseDetailsId, prepareOrderRequest.getPrice(), expenseDetailsPricePayable, reductionPrice);
        }
        if (ObjectUtils.isEmpty(pricePayable)) {
            pricePayable = prepareOrderRequest.getPricePayable();
        }
        OrderInfo orderInfo = BeanUtil.copyProperties(prepareOrderRequest, OrderInfo.class);
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
        String dateString = sdf.format(new Date());
        String tcWaybillNo = "FY" + dateString + UUID.randomUUID().toString().replaceAll("-", "").substring(0, 6);
        Date date = new Date();
        String userId = JwtUtil.getUserId();


        BigDecimal price = prepareOrderRequest.getPrice();


        if (!ObjectUtils.isEmpty(userCouponId)) {
            UserCoupon userCoupon = userCouponRest.getEffectiveCoupon(pricePayable, userCouponId);
            if (ObjectUtils.isEmpty(userCoupon)) {
                throw new RuntimeException("优惠券已失效，请使用其他优惠券");
            }
        }

        orderInfo.setOrderStatus(OrderStatusEnum.TO_BE_PAID.getStatus());
        orderInfo.setUserId(userId);
        orderInfo.setOrderType(prepareOrderRequest.getProductType());
        orderInfo.setCreateTime(date);
        orderInfo.setUpdateTime(date);
        orderInfo.setTcWaybillNo(tcWaybillNo);
        orderInfo.setPricePayable(pricePayable);
        orderInfo.setPricePaid(price);
        orderInfo.setUserCouponId(userCouponId);
        orderInfo.setGoodsTypeId(prepareOrderRequest.getGoodsTypeId());
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, 30);
        orderInfo.setExpireTime(c.getTime());
        Integer webType = prepareOrderRequest.getWebType();
        if (!ObjectUtils.isEmpty(webType) && 1 == webType) {
            //h5
            orderInfo.setPlatformCode(PlatformCodeEnum.CX.getCode());
        } else {
            //小程序
            orderInfo.setPlatformCode(PlatformCodeEnum.FY_EXPRESS.getCode());
        }

        iOrderInfoService.insert(orderInfo);


        UserCoupon userCoupon = userCouponMapper.selectById(userCouponId);
        if (!ObjectUtils.isEmpty(userCoupon)) {
            userCoupon.setStatus(UserCouponStatusEnum.USED.getValue());
            userCoupon.setUseTime(date);
            userCoupon.setUpdateTime(date);
            userCouponMapper.updateById(userCoupon);
            String couponId = userCoupon.getCouponId();
            Coupon coupon = couponMapper.selectById(couponId);
            if (!ObjectUtils.isEmpty(coupon)) {
                Integer usedNum = coupon.getUsedNum();
                if (ObjectUtils.isEmpty(usedNum)) {
                    usedNum = 0;
                }
                coupon.setUsedNum(usedNum + 1);
                couponMapper.updateById(coupon);
            }
        }

        PlaceOrderResponse placeOrderResponse = new PlaceOrderResponse();
        placeOrderResponse.setOrderId(orderInfo.getId());
        //支付
        TradePayLiteResponse response;
        TradePayLiteRequest request = new TradePayLiteRequest();
        Map<String, Object> channelExtra = new HashMap<>(2);

        String openId;
        if (!ObjectUtils.isEmpty(webType) && 1 == webType) {
            //h5
            channelExtra.put("app_id", sfAppid);
            logger.info("sfAppid:", sfAppid);
            logger.info("channelExtra:", channelExtra);
            openId = (String) redisTemplate.opsForValue().get(ServicePrefixEnum.SAME_CITY_H5 + RedisPrefixKey.APPLET_OPENID + userId);
        } else {
            channelExtra.put("app_id", appid);
            //小程序
            openId = (String) redisTemplate.opsForValue().get(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.APPLET_OPENID + userId);
        }

        if (ObjectUtils.isEmpty(openId)) {
            String loginCode = prepareOrderRequest.getLoginCode();
            openId = this.getNewOpenId(loginCode);
        }
        if (ObjectUtils.isEmpty(openId)) {
            throw new RuntimeException("openId缺失，请重新登录再下单");
        }
        channelExtra.put("open_id", openId);
        request.setOutTradeNo(tcWaybillNo).setAmount(orderInfo.getPricePaid().multiply(new BigDecimal(100)).longValue()).setChannel("wxpay").setChannelExtra(channelExtra).setClientIp("127.0.0.1").setSubject(OrderSubjectEnum.getName(OrderSubjectEnum.EXPRESS_FEE.getValue())).setBody("Test-body")
                // 可互联网访问的回调地址
                .setNotifyUrl(callbackUrl + notifyUrl);
        logger.info("request:{}", request);
        response = OpenClient.request(request);
        logger.info("response:{}", response);
        if (!ObjectUtils.isEmpty(response.getCrdlInfo())) {
            Map<String, String> stringStringTreeMap = (Map<String, String>) response.getCrdlInfo().getCrdlData();
            Iterator iterator = stringStringTreeMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                if (entry.getKey().equals("timeStamp")) {
                    placeOrderResponse.setTimeStamp((String) entry.getValue());
                } else if (entry.getKey().equals("nonceStr")) {
                    placeOrderResponse.setNonceStr((String) entry.getValue());
                } else if (entry.getKey().equals("package")) {
                    placeOrderResponse.setPackageString((String) entry.getValue());
                } else if (entry.getKey().equals("signType")) {
                    placeOrderResponse.setSignType((String) entry.getValue());
                } else if (entry.getKey().equals("paySign")) {
                    placeOrderResponse.setPaySign((String) entry.getValue());
                }
            }
        }
        this.dealAfterPlaceOrder(orderInfo.getId());
        //将省-市记录到order-extra表
        OrderExtraRequest orderExtraRequest = new OrderExtraRequest();
        orderExtraRequest.setCreateTime(date);
        orderExtraRequest.setUpdateTime(date);
        orderExtraRequest.setOrderId(orderInfo.getId());
        orderExtraRequest.setFromProvince(fromProvince);
        orderExtraRequest.setFromCity(fromCity);
        orderExtraRequest.setToProvince(toProvince);
        orderExtraRequest.setToCity(toCity);
        orderExtraRequest.setFromDistrict(fromDistrict);
        orderExtraRequest.setToDistrict(toDistrict);
        orderExtraController.add(orderExtraRequest);


        PaySetting paySetting = BeanUtil.copyProperties(placeOrderResponse, PaySetting.class);
        paySetting.setWebType(webType);
        redisTemplate.opsForValue().set(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.PAY_SETTING + orderInfo.getId(), paySetting);
        redisTemplate.expire(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.PAY_SETTING + orderInfo.getId(), 30, TimeUnit.MINUTES);
        if (response.isSuccess()) {
            delayQueue.pushQueue(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.ORDER_COUNT_DOWN + orderInfo.getId(), c.getTime().getTime() - date.getTime());
            // 支付链接 由客户端转成二维码提供用户扫码支付
            return placeOrderResponse;
        }
        return null;
    }

    @Override
    public String placeOrderForH5(PrepareOrderForH5Request prepareOrderRequest) {
        logger.info(prepareOrderRequest.toString());
        String senderTel = prepareOrderRequest.getSenderTel();
        String receiverTel = prepareOrderRequest.getReceiverTel();
        MobileNumberValidatorUtil.checkPhone(senderTel);
        MobileNumberValidatorUtil.checkPhone(receiverTel);
        String expenseDetailsId = prepareOrderRequest.getExpenseDetailsId();
        String userCouponId = prepareOrderRequest.getUserCouponId();
        //校验价格是否被篡改
        BigDecimal pricePayable = null;
        if (!ObjectUtils.isEmpty(expenseDetailsId)) {
            pricePayable = iOrderInfoService.checkPrice(expenseDetailsId, prepareOrderRequest.getPrice());
        }
        if (ObjectUtils.isEmpty(pricePayable)) {
            pricePayable = prepareOrderRequest.getPricePayable();
        }
        OrderInfo orderInfo = BeanUtil.copyProperties(prepareOrderRequest, OrderInfo.class);
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
        String dateString = sdf.format(new Date());
        String tcWaybillNo = "FY" + dateString + UUID.randomUUID().toString().replaceAll("-", "").substring(0, 6);
        Date date = new Date();
        String userId = JwtUtil.getUserId();


        BigDecimal price = prepareOrderRequest.getPrice();


        if (!ObjectUtils.isEmpty(userCouponId)) {
            UserCoupon userCoupon = userCouponRest.getEffectiveCoupon(pricePayable, userCouponId);
            if (ObjectUtils.isEmpty(userCoupon)) {
                throw new RuntimeException("优惠券已失效，请使用其他优惠券");
            }
        }

        orderInfo.setOrderStatus(OrderStatusEnum.TO_BE_PAID.getStatus());
        orderInfo.setUserId(userId);
        orderInfo.setCreateTime(date);
        orderInfo.setUpdateTime(date);
        orderInfo.setTcWaybillNo(tcWaybillNo);
        orderInfo.setPricePayable(pricePayable);
        orderInfo.setPricePaid(price);
        orderInfo.setUserCouponId(userCouponId);
        orderInfo.setGoodsTypeId(prepareOrderRequest.getGoodsTypeId());
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, 30);
        orderInfo.setExpireTime(c.getTime());
        orderInfo.setPlatformCode(PlatformCodeEnum.FY_EXPRESS.getCode());
        iOrderInfoService.insert(orderInfo);


        UserCoupon userCoupon = userCouponMapper.selectById(userCouponId);
        if (!ObjectUtils.isEmpty(userCoupon)) {
            userCoupon.setStatus(UserCouponStatusEnum.USED.getValue());
            userCoupon.setUseTime(date);
            userCoupon.setUpdateTime(date);
            userCouponMapper.updateById(userCoupon);
            String couponId = userCoupon.getCouponId();
            Coupon coupon = couponMapper.selectById(couponId);
            if (!ObjectUtils.isEmpty(coupon)) {
                Integer usedNum = coupon.getUsedNum();
                if (ObjectUtils.isEmpty(usedNum)) {
                    usedNum = 0;
                }
                coupon.setUsedNum(usedNum + 1);
                couponMapper.updateById(coupon);
            }
        }

        PlaceOrderResponse placeOrderResponse = new PlaceOrderResponse();
        placeOrderResponse.setOrderId(orderInfo.getId());


        String formData = this.h5Pay(orderInfo.getPricePaid(), tcWaybillNo);
        this.dealAfterPlaceOrder(orderInfo.getId());
        redisTemplate.expire(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.PAY_SETTING + orderInfo.getId(), 30, TimeUnit.MINUTES);
        delayQueue.pushQueue(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.ORDER_COUNT_DOWN + orderInfo.getId(), c.getTime().getTime() - date.getTime());
        return formData;
    }

    public String h5Pay(BigDecimal pricePaid, String tcWaybillNo) {
        long price = (pricePaid.multiply(new BigDecimal(100))).longValue();
        logger.info("tcWaybillNo:{}", tcWaybillNo);
        TradePayH5cashierRequest tradePayH5cashierRequest = new TradePayH5cashierRequest().setAmount(price).setOutTradeNo(tcWaybillNo).setSubject("H5-丰翼配送").setBody("丰翼配送").setClientIp("10.216.230.170").setChannel("wxpay").setReturnUrl(sitUrl + "/pay/notification/wxpay").setNotifyUrl(callbackUrl + notifyUrl);
        ApiResponse apiResponse = OpenClient.pageExecute(tradePayH5cashierRequest);
        return apiResponse.getBody();
    }


    @Override
    public String getNewOpenId(String loginCode) {
        Object object;
        object = redisTemplate.opsForValue().get(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.WX_LOGIN_DATA + loginCode);
        if (ObjectUtils.isEmpty(object)) {
            object = loginService.decipheringCode(loginCode);
        }
        return (String) ((JSONObject) object).get("openid");
    }

    @Async
    public void dealAfterPlaceOrder(String orderInfoId) {
        OrderInfo orderInfo = orderInfoMapper.selectById(orderInfoId);
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new RuntimeException("订单不存在");
        }
        Date date = orderInfo.getCreateTime();
        TaskStatusLog taskStatusLog = new TaskStatusLog();
        taskStatusLog.setStatus(orderInfo.getOrderStatus());
        taskStatusLog.setTaskId(orderInfo.getId());
        taskStatusLog.setCreateTime(date);
        taskStatusLog.setUpdateTime(date);
        taskStatusLog.setUserId(orderInfo.getUserId());
        taskStatusLogRest.add(taskStatusLog);
        TaskGoods taskGoods = new TaskGoods();
        taskGoods.setTaskId(orderInfo.getId());
        taskGoods.setGoodsTypeId(orderInfo.getGoodsTypeId());
        taskGoods.setCreateTime(date);
        taskGoods.setUpdateTime(date);
        taskGoodsMapper.insert(taskGoods);
    }


    @Override
    public JSONObject selectOrder(SelectOrderRequest selectOrderRequest) {
        return intraCityRest.selectOrder(selectOrderRequest);
    }

    @Override
    public void add(FeedbackRequest feedbackRequest) {
        UserResponse userResponse = userRest.getByUserId(feedbackRequest.getUserId());
        feedbackRequest.setPhoneNumber(userResponse.getPhoneNumber());
        Feedback feedback = feedbackRest.add(feedbackRequest);
        FeedbackStatusLog feedbackStatusLog = new FeedbackStatusLog();
        feedbackStatusLog.setFeedbackId(feedback.getId());
        feedbackStatusLog.setUserId(feedback.getUserId());
        feedbackStatusLog.setStatus(FeedbackStatusEnum.SUBMITTED.getStatus());
        feedbackStatusLogRest.add(feedbackStatusLog);
    }

    @Override
    public FeedbackDetailsResponse getFeedback(String orderId) {
        FeedbackDetailsResponse feedbackDetailsResponse = new FeedbackDetailsResponse();
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if (!ObjectUtils.isEmpty(orderInfo)) {
            feedbackDetailsResponse = BeanUtil.copyProperties(orderInfo, FeedbackDetailsResponse.class);
        }
        List<FeedbackResponse> feedbackResponses = new ArrayList<>();
        QueryWrapper<Feedback> feedbackQueryWrapper = new QueryWrapper<>();
        feedbackQueryWrapper.eq("order_id", orderId);
        List<Feedback> feedbacks = iFeedbackService.selectList(feedbackQueryWrapper);
        for (Feedback feedback : feedbacks) {
            FeedbackResponse feedbackResponse = BeanUtil.copyProperties(feedback, FeedbackResponse.class);
            FeedbackType feedbackType = feedbackTypeMapper.selectById(feedback.getFeedbackTypeId());
            if (!ObjectUtils.isEmpty(feedbackType)) {
                feedbackResponse.setFeedbackTypeName(feedbackType.getName());
            }
            feedbackResponses.add(feedbackResponse);
        }

        feedbackDetailsResponse.setFeedbackResponses(feedbackResponses);
        return feedbackDetailsResponse;
    }

    @Override
    public PlaceOrderResponse getPaySettings(String orderId) {
        return paySettingRest.getPaySettings(orderId);
    }


    @Override
    public Object confirmPay(ConfirmPayRequest confirmPayRequest) {
        logger.info("confirmPayRequest" + confirmPayRequest.toString());
        Date date = new Date();
        QueryWrapper<OrderInfo> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.eq("tc_waybill_no", confirmPayRequest.getOutTradeNo());
        OrderInfo orderInfo = orderInfoMapper.selectOne(orderQueryWrapper);
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new RuntimeException("交易号不存在，请联系客服");
        }
        if (OrderStatusEnum.TO_BE_PAID.getStatus().equals(orderInfo.getOrderStatus())) {
            orderInfo.setPayChannel(confirmPayRequest.getPayChannel());
            orderInfo.setSettleChannel(confirmPayRequest.getSettleChannel());
            orderInfo.setOrderStatus(OrderStatusEnum.PENDING_ITEMS.getStatus());
            Integer platformCode = orderInfo.getPlatformCode();
            orderInfo.setTransactionTime(date);
            orderInfo.setTradeNo(confirmPayRequest.getTradeNo());
            orderInfo.setSfpayPayNo(confirmPayRequest.getSfpayPayNo());
            orderInfo.setChannelPayNo(confirmPayRequest.getChannelPayNo());
            orderInfo.setUpdateTime(date);


            //去下单
            PlaceOrderRequest placeOrderRequest = BeanUtil.copyProperties(orderInfo, PlaceOrderRequest.class);

            String senderTel = placeOrderRequest.getSenderTel();
            String receiverTel = placeOrderRequest.getReceiverTel();

            String senderDoorplate = placeOrderRequest.getSenderDoorplate();
            String receiverDoorplate = placeOrderRequest.getReceiverDoorplate();
            senderTel = phoneEncoderUtil.decryptString(senderTel);
            receiverTel = phoneEncoderUtil.decryptString(receiverTel);

            senderDoorplate = phoneEncoderUtil.decryptString(senderDoorplate);
            receiverDoorplate = phoneEncoderUtil.decryptString(receiverDoorplate);
            placeOrderRequest.setSenderTel(senderTel);
            placeOrderRequest.setReceiverTel(receiverTel);
            placeOrderRequest.setSenderDoorplate(senderDoorplate);
            placeOrderRequest.setReceiverDoorplate(receiverDoorplate);

            placeOrderRequest.setAmount(orderInfo.getPricePaid().doubleValue());
            //平台组限制统一传1
            placeOrderRequest.setGoodsType(1);
            if (!ObjectUtils.isEmpty(orderInfo.getSendAddressName())) {
                placeOrderRequest.setSenderAddr(orderInfo.getSenderAddr() + orderInfo.getSendAddressName());
            }
            if (!ObjectUtils.isEmpty(orderInfo.getReceiveAddressName())) {
                placeOrderRequest.setReceiverAddr(orderInfo.getReceiverAddr() + orderInfo.getReceiveAddressName());
            }

            if (!ObjectUtils.isEmpty(orderInfo.getReceiverAreaCode())) {
                placeOrderRequest.setReceiverTel(orderInfo.getReceiverAreaCode() + "-" + placeOrderRequest.getReceiverTel());
            }
            if (!ObjectUtils.isEmpty(orderInfo.getSenderAreaCode())) {
                placeOrderRequest.setSenderTel(orderInfo.getSenderAreaCode() + "-" + placeOrderRequest.getSenderTel());
            }
            if (!ObjectUtils.isEmpty(orderInfo.getSenderDoorplate())) {
                placeOrderRequest.setSenderAddr(placeOrderRequest.getSenderAddr() + placeOrderRequest.getSenderDoorplate());
            }
            if (!ObjectUtils.isEmpty(orderInfo.getReceiverDoorplate())) {
                placeOrderRequest.setReceiverAddr(placeOrderRequest.getReceiverAddr() + placeOrderRequest.getReceiverDoorplate());
            }
            double transfer = orderInfo.getGoodsWeight() * 1000;
            placeOrderRequest.setGoodsWeight((int) transfer);

            //记录任务日志
            TaskStatusLog taskStatusLog = new TaskStatusLog();
            taskStatusLog.setStatus(OrderStatusEnum.PENDING_ITEMS.getStatus());

            String orderId = orderInfo.getId();
            //发送丰声新订单提醒消息
//            delayQueue.pushQueue(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.SEND_NEW_ORDER_FS_MSG + orderId, 0L);
            taskStatusLog.setTaskId(orderId);
            taskStatusLog.setCreateTime(date);
            taskStatusLog.setUpdateTime(date);
            taskStatusLog.setUserId(orderInfo.getUserId());
            taskStatusLogRest.add(taskStatusLog);
            Calendar c = Calendar.getInstance();
            c.setTime(date);

            c.add(Calendar.MINUTE, 5);
            //发送丰声订单接单提醒
            String msg = ServicePrefixEnum.SAME_CITY + RedisPrefixKey.SEND_FS_NOTICE + orderId;
//            delayQueue.pushQueue2(msg, c.getTime().getTime());

            //发送丰声订单超时预警提醒
//            delayQueue.pushQueue(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.SEND_FS_OVERTIME_WARNING_NOTICE + orderId, 0L);

            //发送丰声订单超时提醒
//            delayQueue.pushQueue(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.SEND_FS_OVERTIME_NOTICE + orderId, 0L);

            if (!PlatformCodeEnum.MONTHLY_SETTLEMENT_PLATFORM.getCode().equals(platformCode)) {
                //月结下单成功再发
                delayQueue.pushQueue(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.SEND_NOTICE + orderId, 0L);
            }

            logger.info("placeOrderRequest:{}" + placeOrderRequest);
            JSONObject jsonObject = intraCityRest.placeOrder(placeOrderRequest);
            if (jsonObject.getBoolean("success")) {
                if (PlatformCodeEnum.MONTHLY_SETTLEMENT_PLATFORM.getCode().equals(platformCode)) {
                    //月结下单成功再发
                    delayQueue.pushQueue(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.SEND_NOTICE + orderId, 0L);
                }
                String takeoffConnId = jsonObject.getJSONObject("obj").getString("takeoffConnId");
                String landingConnId = jsonObject.getJSONObject("obj").getString("landingConnId");
                orderInfo.setTakeoffConnId(takeoffConnId);
                orderInfo.setLandingConnId(landingConnId);
                orderInfoMapper.updateById(orderInfo);
                this.addOverTimeNotice(date, orderId);
                this.dealPlaceOrder(jsonObject, date, orderId);
                logger.info("下单成功");


                //平台立即接单
//                this.dealOrderAuto(orderInfo.getTcWaybillNo());
                return null;
            } else {
                logger.info("进入取消订单流程");
                logger.info(RootContext.getXID());
                orderInfoMapper.updateById(orderInfo);
                //退款并更新状态为已取消
                IdRequest idRequest = new IdRequest();
                idRequest.setId(orderId);
                idRequest.setWrongMsg(jsonObject.getString("errorMessage"));
                taskController.cancelOrder(idRequest);
                logger.info(jsonObject.getString("errorMessage"));
                throw new RuntimeException(jsonObject.getString("errorMessage"));
            }
        }
        return null;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Object confirmPayNoTransactional(ConfirmPayRequest confirmPayRequest) {
        return this.confirmPay(confirmPayRequest);
    }

    public void dealOrderAuto(String tcWaybillNo) {
        UpdateOrderInfoStatusRequest updateOrderInfoStatusRequest = new UpdateOrderInfoStatusRequest();
        updateOrderInfoStatusRequest.setOrderStatus(OrderStatusEnum.DOOR_TO_DOOR_PICKUP.getStatus());
        updateOrderInfoStatusRequest.setTcWaybillNo(tcWaybillNo);
        updateOrderInfoStatusRequest.setProcessedBy("admin");
        orderController.updateStatus(updateOrderInfoStatusRequest);
    }

    public void addOverTimeNotice(Date date, String orderId) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        String key = ServicePrefixEnum.SAME_CITY.toString();
        key += RedisPrefixKey.PENDING_ITEMS_DOWN;
        c.add(Calendar.MINUTE, countDownPendingItems);
        logger.info("添加通知redis key：" + key + orderId);
        delayQueue.pushQueue(key + orderId, c.getTime().getTime() - date.getTime());
    }

    @Async
    public void dealPlaceOrder(JSONObject jsonObject, Date date, String orderId) {
        String fyCode = jsonObject.getJSONObject("obj").getString("fyCode");
        String takeoffConnId = jsonObject.getJSONObject("obj").getString("takeoffConnId");
        String landingConnId = jsonObject.getJSONObject("obj").getString("landingConnId");
        Integer orderType = jsonObject.getJSONObject("obj").getInteger("orderType");
        String flightTime = jsonObject.getJSONObject("obj").getString("flightTime");
        String fyReceiverName = jsonObject.getJSONObject("obj").getString("fyReceiverName");
        String fyReceiverTel = jsonObject.getJSONObject("obj").getString("fyReceiverTel");
        String fySenderName = jsonObject.getJSONObject("obj").getString("fySenderName");
        String fySenderTel = jsonObject.getJSONObject("obj").getString("fySenderTel");
        String sendAirRoute = jsonObject.getJSONObject("obj").getString("sendAirRoute");
        Integer gpsType = jsonObject.getJSONObject("obj").getInteger("gpsType");


        String landingLon = jsonObject.getJSONObject("obj").getString("landingLon");
        String landingLat = jsonObject.getJSONObject("obj").getString("landingLat");
        String landingName = jsonObject.getJSONObject("obj").getString("landingName");
        String landingAddr = jsonObject.getJSONObject("obj").getString("landingAddr");

        String takeoffLon = jsonObject.getJSONObject("obj").getString("takeoffLon");
        String takeoffLat = jsonObject.getJSONObject("obj").getString("takeoffLat");
        String takeoffName = jsonObject.getJSONObject("obj").getString("takeoffName");
        String takeoffAddr = jsonObject.getJSONObject("obj").getString("takeoffAddr");
        CityAirport cityAirport = cityAirportRest.selectByConnId(takeoffConnId);
        if (ObjectUtils.isEmpty(cityAirport)) {
            CityAirportAddRequest cityAirportAddRequest = new CityAirportAddRequest();
            cityAirportAddRequest.setAddr(takeoffAddr);
            cityAirportAddRequest.setConnId(takeoffConnId);
            cityAirportAddRequest.setName(takeoffName);
            cityAirportAddRequest.setLat(takeoffLat);
            cityAirportAddRequest.setLon(takeoffLon);
            cityAirportAddRequest.setCreateTime(date);
            cityAirportAddRequest.setUpdateTime(date);
            cityAirportRest.add(cityAirportAddRequest);
        }

        CityAirport endCityAirport = cityAirportRest.selectByConnId(landingConnId);
        if (ObjectUtils.isEmpty(endCityAirport)) {
            CityAirportAddRequest cityAirportAddRequest = new CityAirportAddRequest();
            cityAirportAddRequest.setAddr(landingAddr);
            cityAirportAddRequest.setConnId(landingConnId);
            cityAirportAddRequest.setName(landingName);
            cityAirportAddRequest.setLat(landingLat);
            cityAirportAddRequest.setLon(landingLon);
            cityAirportAddRequest.setCreateTime(date);
            cityAirportAddRequest.setUpdateTime(date);
            cityAirportRest.add(cityAirportAddRequest);
        }
        OrderExtra orderExtra = orderExtraController.getByOrderId(orderId);
        if (!ObjectUtils.isEmpty(orderExtra)) {
            orderExtra.setSendAirRoute(sendAirRoute);
            orderExtra.setFyCode(fyCode);
            orderExtra.setOrderType(orderType);
            orderExtra.setFlightTime(flightTime);
            orderExtra.setUpdateTime(date);
            orderExtra.setFyReceiverName(fyReceiverName);
            orderExtra.setFyReceiverTel(phoneEncoderUtil.encryptString(fyReceiverTel));
            orderExtra.setFySenderName(fySenderName);
            orderExtra.setFySenderTel(phoneEncoderUtil.encryptString(fySenderTel));
            orderExtra.setGpsType(gpsType);
            orderExtraMapper.updateById(orderExtra);
        }

    }

    @Override
    public void sendPaySuccessMsg(String orderId) {

        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new RuntimeException("订单记录为空");
        }
        String userId = orderInfo.getUserId();
        Date updateTime = orderInfo.getUpdateTime();


        BillAddRequest billAddRequest = new BillAddRequest();
        billAddRequest.setOrderId(orderInfo.getId());
        billAddRequest.setTcWaybillNo(orderInfo.getTcWaybillNo());
        billAddRequest.setPricePaid(orderInfo.getPricePaid());
        if (orderInfo.getPlatformCode().equals(PlatformCodeEnum.FY_EXPRESS.getCode()) || orderInfo.getPlatformCode().equals(PlatformCodeEnum.CX.getCode())) {
            billAddRequest.setPayStatus(PayStatusEnum.SUCCESS.getValue());
        } else if (orderInfo.getPlatformCode().equals(PlatformCodeEnum.MONTHLY_SETTLEMENT_PLATFORM.getCode())) {
            billAddRequest.setPayStatus(PayStatusEnum.TO_BE_SETTLED.getValue());
        }
        billAddRequest.setUserId(userId);
        billAddRequest.setUpdateTime(updateTime);
        billAddRequest.setType(OrderTypeEnum.INCOME.getValue());
        billRest.add(billAddRequest);


//        //通知变更
//        String accessToken = loginService.getAccessToken();
//        String templateId;
//        HashMap data = new HashMap();
//        String openId = (String) redisTemplate.opsForValue().get(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.APPLET_OPENID + userId);
//        templateId = updateStatusTemplateId;
//        //状态变更
//        Map character_string13 = new HashMap();
//        character_string13.put("value", tcWaybillNo);
//        Map phrase3 = new HashMap();
//        phrase3.put("value", OrderStatusEnum.getName(orderStatus));
//        Map thing18 = new HashMap();
//        CityGoodsType cityGoodsType = cityGoodsTypeMapper.selectById(goodsTypeId);
//        thing18.put("value", ObjectUtils.isEmpty(cityGoodsType) ? "--" : cityGoodsType.getName());
//        Map thing4 = new HashMap();
//        thing4.put("value", "小主，小哥正在马不停蹄的赶来~");
//        data.put("character_string13", character_string13);
//        data.put("phrase3", phrase3);
//        data.put("thing18", thing18);
//        data.put("thing4", thing4);
//        wxAppletRest.subscribeSend(accessToken, templateId, openId, data, "pages/tasks/details/details?taskId=" + orderId + "&backHome=1");


        QueryWrapper<InvitationRecord> invitationRecordQueryWrapper = new QueryWrapper<>();
        invitationRecordQueryWrapper.eq("user_id", userId);
        InvitationRecord invitationRecord = invitationRecordMapper.selectOne(invitationRecordQueryWrapper);
        if (!ObjectUtils.isEmpty(invitationRecord)) {
            String invitationCodeId = invitationRecord.getInvitationCodeId();
            InvitationCode invitationCode = invitationCodeMapper.selectById(invitationCodeId);
            if (!ObjectUtils.isEmpty(invitationCode)) {
                String invitationUserId = invitationCode.getUserId();
                String activityId = invitationCode.getActivityId();
                Activity activity = activityRest.getSettings(activityId);
                if (!ObjectUtils.isEmpty(activity)) {
                    Date date = new Date();
                    PromotionRecords promotionRecords = new PromotionRecords();
                    promotionRecords.setActivityId(activityId);
                    promotionRecords.setCreateTime(date);
                    promotionRecords.setUpdateTime(date);
                    promotionRecords.setTcWaybillNo(orderInfo.getTcWaybillNo());
                    promotionRecords.setOrderTime(orderInfo.getCreateTime());
                    promotionRecords.setPromotionUserId(invitationUserId);
                    User invitationUser = userMapper.selectById(invitationUserId);
                    if (!ObjectUtils.isEmpty(invitationUser)) {
                        promotionRecords.setPromotionPhoneNumber(invitationUser.getPhoneNumber());
                    }
                    User user = userMapper.selectById(userId);
                    if (!ObjectUtils.isEmpty(user)) {
                        promotionRecords.setPayerPhoneNumber(user.getPhoneNumber());
                    }
                    promotionRecords.setPayerUserId(userId);
                    promotionRecordsMapper.insert(promotionRecords);

                }
            }
        }
    }

    @Override
    public void sendFsNoticeMsg(String orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if (!ObjectUtils.isEmpty(orderInfo)) {
            /*
             * 变更为等待接单，需要向丰声推送消息
             * 1、组装消息
             */
            OrderExtra orderExtra = orderExtraController.getByOrderId(orderInfo.getId());
            CityAirport takeoffCityAirport = cityAirportRest.selectByConnId(orderInfo.getTakeoffConnId());
            if (!ObjectUtils.isEmpty(orderExtra) && !ObjectUtils.isEmpty(takeoffCityAirport)) {
                // 计算时间差
                Duration duration = Duration.between(orderInfo.getUpdateTime().toInstant(), new Date().toInstant());
                // 输出相差的分钟数
                long minutes = duration.toMinutes();
                minutes = minutes / 5 * 5;
                if (minutes != 0) {
                    String fsTxt = "【订单接单提醒】：丰翼配送订单" + orderInfo.getTcWaybillNo() + "，流向：" + orderExtra.getFromCity() + orderExtra.getFromDistrict() + " 至 " + orderExtra.getToCity() + orderExtra.getToDistrict() + "，揽件航站：" + takeoffCityAirport.getName() + "，" + minutes + "分钟未接单，请及时跟进处理。";
                    JSONObject a = sysFsRest.getAccessToken();
                    String batchId = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 30);
                    sysFsRest.sendFsSms(a.getString("access_token"), batchId, fsTxt, "【订单接单提醒】");
                    //设置下一轮提醒
                    Calendar c = Calendar.getInstance();
                    c.setTime(orderInfo.getUpdateTime());
                    c.add(Calendar.MINUTE, (int) minutes + 5);
                    //发送丰声订单接单提醒

                    String msg = ServicePrefixEnum.SAME_CITY + RedisPrefixKey.SEND_FS_NOTICE + orderId;
                    delayQueue.pushQueue2(msg, c.getTime().getTime());
                }
            }
        }
    }

    @Override
    public void sendNewOrderFsNoticeMsg(String orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if (!ObjectUtils.isEmpty(orderInfo)) {
            /*
             * 变更为等待接单，需要向丰声推送消息
             * 1、组装消息
             */
            OrderExtra orderExtra = orderExtraController.getByOrderId(orderId);
            CityAirport takeoffCityAirport = cityAirportRest.selectByConnId(orderInfo.getTakeoffConnId());
            try {
                if (!ObjectUtils.isEmpty(orderExtra) && !ObjectUtils.isEmpty(takeoffCityAirport)) {
                    String fsTxt = "【新订单提醒】：丰翼配送订单" + orderInfo.getTcWaybillNo() + "，流向：" + orderExtra.getFromCity() + orderExtra.getFromDistrict() + " 至 " + orderExtra.getToCity() + orderExtra.getToDistrict() + "，揽件航站：" + takeoffCityAirport.getName() + "，请及时跟进处理。";
                    logger.info(fsTxt);
                    JSONObject a = sysFsRest.getAccessToken();
                    String batchId = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 30);
                    sysFsRest.sendFsSms(a.getString("access_token"), batchId, fsTxt, "【新订单提醒】");
                }
            } catch (Exception e) {
                logger.info(e.toString());
            }

        }

    }

    @Override
    public void sendFsOvertimeWarningNoticeMsg(String orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if (!ObjectUtils.isEmpty(orderInfo)) {
            /*
             * 变更为等待接单，需要向丰声推送消息
             * 1、组装消息
             */
            OrderExtra orderExtra = orderExtraController.getByOrderId(orderInfo.getId());
            if (!ObjectUtils.isEmpty(orderExtra)) {
                String fsTxt = "【订单超时预警】：丰翼配送订单" + orderInfo.getTcWaybillNo() + "，当前状态" + OrderStatusEnum.getName(orderInfo.getOrderStatus()) + "，流向：" + orderExtra.getFromCity() + orderExtra.getFromDistrict() + " 至 " + orderExtra.getToCity() + orderExtra.getToDistrict() + "，30分钟后将超时送达，请及时跟进处理。";
                JSONObject a = sysFsRest.getAccessToken();
                String batchId = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 30);
                sysFsRest.sendFsSms(a.getString("access_token"), batchId, fsTxt, "【订单超时预警】");
            }
        }
    }

    @Override
    public void sendFsOvertimeNoticeMsg(String orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if (!ObjectUtils.isEmpty(orderInfo)) {
            /*
             * 变更为等待接单，需要向丰声推送消息
             * 1、组装消息
             */
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            OrderExtra orderExtra = orderExtraController.getByOrderId(orderInfo.getId());
            CityAirport landingCityAirport = cityAirportRest.selectByConnId(orderInfo.getLandingConnId());
            if (!ObjectUtils.isEmpty(orderExtra) && !ObjectUtils.isEmpty(landingCityAirport)) {
                String fsTxt = "【订单超时提醒】：丰翼配送订单" + orderInfo.getTcWaybillNo() + "，下单时间：" + sdf.format(orderInfo.getTransactionTime()) + "，当前状态：" + OrderStatusEnum.getName(orderInfo.getOrderStatus()) + "派件航站：" + landingCityAirport.getName() + "，已超时未送达订单，请及时跟进处理。";
                JSONObject a = sysFsRest.getAccessToken();
                String batchId = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 30);
                sysFsRest.sendFsSms(a.getString("access_token"), batchId, fsTxt, "【订单超时提醒】");
            }
        }
    }

    @Override
    public FeeDetailsResponse getFeeDetails(String orderId) {
        FeeDetailsResponse feeDetailsResponse = new FeeDetailsResponse();
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if (!ObjectUtils.isEmpty(orderInfo)) {
            String expenseDetailsId = orderInfo.getExpenseDetailsId();
            if (!ObjectUtils.isEmpty(expenseDetailsId)) {
                ExpenseDetails expenseDetails = expenseDetailsMapper.selectById(expenseDetailsId);
                feeDetailsResponse = BeanUtil.copyProperties(expenseDetails, FeeDetailsResponse.class);
            }
        }
        return feeDetailsResponse;
    }

    @Override
    public PublicOrderDetailResponse getPublicOrderDetail(String id) {
        OrderInfo orderInfo = orderInfoMapper.selectById(id);
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new RuntimeException("订单不存在");
        }
        String senderTel = orderInfo.getSenderTel();
        String receiverTel = orderInfo.getReceiverTel();
        senderTel = phoneEncoderUtil.decryptString(senderTel);
        receiverTel = phoneEncoderUtil.decryptString(receiverTel);

        senderTel = PhoneEncoderUtil.desensitization(senderTel);
        receiverTel = PhoneEncoderUtil.desensitization(receiverTel);
        orderInfo.setSenderTel(senderTel);
        orderInfo.setReceiverTel(receiverTel);
        PublicOrderDetailResponse publicOrderDetailResponse = BeanUtil.copyProperties(orderInfo, PublicOrderDetailResponse.class);
        QueryWrapper<TaskGoods> taskGoodsQueryWrapper = new QueryWrapper<>();
        taskGoodsQueryWrapper.eq("task_id", orderInfo.getId());
        //获取商品信息
        TaskGoods taskGoods = taskGoodsMapper.selectOne(taskGoodsQueryWrapper);
        if (!ObjectUtils.isEmpty(taskGoods)) {
            CityGoodsType cityGoodsType = cityGoodsTypeMapper.selectById(taskGoods.getGoodsTypeId());
            if (!ObjectUtils.isEmpty(cityGoodsType)) {
                PublicGoodsTypeResponse publicGoodsTypeResponse = BeanUtil.copyProperties(taskGoods, PublicGoodsTypeResponse.class);
                publicGoodsTypeResponse.setGoodsTypeName(cityGoodsType.getName());
                publicOrderDetailResponse.setPublicGoodsTypeResponse(publicGoodsTypeResponse);
            }
        }
        if (!orderInfo.getOrderStatus().equals(OrderStatusEnum.TO_BE_PAID.getStatus())) {
            //获取订单最新信息
            SelectOrderRequest selectOrderRequest = new SelectOrderRequest();
            selectOrderRequest.setTcWaybillNo(orderInfo.getTcWaybillNo());
        }


        //取件/派件中获取骑手坐标
        Integer orderStatus = orderInfo.getOrderStatus();
        if (OrderStatusEnum.TO_BE_DISPATCHED.getStatus().equals(orderStatus)) {
            ErrandOrder errandOrder = errandOrderController.getByOrderSn(orderInfo.getTcWaybillNo(), ErrandOrderTypeEnum.DELIVERY.getValue());
            if (!ObjectUtils.isEmpty(errandOrder)) {
                publicOrderDetailResponse.setLatitude(errandOrder.getLatitude());
                publicOrderDetailResponse.setLongitude(errandOrder.getLongitude());
            }

        } else if (OrderStatusEnum.DOOR_TO_DOOR_PICKUP.getStatus().equals(orderStatus) || OrderStatusEnum.DRONE_HAS_BEEN_PICKED_UP.getStatus().equals(orderStatus)) {
            ErrandOrder errandOrder = errandOrderController.getByOrderSn(orderInfo.getTcWaybillNo(), ErrandOrderTypeEnum.COLLECTING.getValue());
            if (!ObjectUtils.isEmpty(errandOrder)) {
                publicOrderDetailResponse.setLatitude(errandOrder.getLatitude());
                publicOrderDetailResponse.setLongitude(errandOrder.getLongitude());
            }

        }

        //获取出发、到达航站接驳ID
        String landingConnId = orderInfo.getLandingConnId();
        String takeoffConnId = orderInfo.getTakeoffConnId();
        //获取派件航站信息
        List<TtTesTerminal> ttTesTerminals = ttTesTerminalRest.selectByConnIds(Arrays.asList(takeoffConnId, landingConnId));
        if (!CollectionUtils.isEmpty(ttTesTerminals)) {
            ttTesTerminals.forEach(ttTesTerminal -> {
                if (landingConnId.equals(ttTesTerminal.getConnId())) {
                    publicOrderDetailResponse.setLandingTerminalLatitude(ttTesTerminal.getLatitude());
                    publicOrderDetailResponse.setLandingTerminalLongitude(ttTesTerminal.getLongitude());
                } else if (takeoffConnId.equals(ttTesTerminal.getConnId())) {
                    publicOrderDetailResponse.setTakeOffTerminalLatitude(ttTesTerminal.getLatitude());
                    publicOrderDetailResponse.setTakeOffTerminalLongitude(ttTesTerminal.getLongitude());
                }
            });
        }
        return publicOrderDetailResponse;
    }

    @Override
    public FeedbackTypeResponse getFeedbackType(String orderId) {
        FeedbackTypeResponse feedbackTypeResponse = new FeedbackTypeResponse();
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if (!ObjectUtils.isEmpty(orderInfo)) {
            feedbackTypeResponse = BeanUtil.copyProperties(orderInfo, FeedbackTypeResponse.class);
        }
        List<FeedbackResponse> feedbackResponses = new ArrayList<>();
        QueryWrapper<Feedback> feedbackQueryWrapper = new QueryWrapper<>();
        feedbackQueryWrapper.eq("order_id", orderId);
        List<Feedback> feedbacks = iFeedbackService.selectList(feedbackQueryWrapper);
        if (ObjectUtils.isEmpty(feedbacks)) {
            List<IdResponse> idResponses = feedbackTypeRest.getAll();
            feedbackTypeResponse.setIdResponses(idResponses);
        } else {
            for (Feedback feedback : feedbacks) {
                FeedbackResponse feedbackResponse = BeanUtil.copyProperties(feedback, FeedbackResponse.class);
                FeedbackType feedbackType = feedbackTypeMapper.selectById(feedback.getFeedbackTypeId());
                if (!ObjectUtils.isEmpty(feedbackType)) {
                    feedbackResponse.setFeedbackTypeName(feedbackType.getName());
                }
                feedbackResponses.add(feedbackResponse);
            }
            feedbackTypeResponse.setFeedbackResponses(feedbackResponses);
        }
        return feedbackTypeResponse;
    }

}
